package com.zlyx.easy.swagger.config;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.maven.model.Developer;
import org.springframework.boot.context.properties.ConfigurationProperties;

import com.fasterxml.classmate.ResolvedType;
import com.zlyx.easy.core.app.AppUtils;
import com.zlyx.easy.core.collections.Lists;
import com.zlyx.easy.core.maven.MavenUtils;
import com.zlyx.easy.core.utils.HostUtils;
import com.zlyx.easy.core.utils.JsonUtils;
import com.zlyx.easy.swagger.model.ResponseMessage;

import springfox.documentation.builders.ParameterBuilder;

/**
 * @Auth 赵光
 * @Describle EasySwagger配置文件
 */
@ConfigurationProperties("easy.swagger")
public class EasySwaggerConfiguration extends AbstractApiConfiguration {

	/**
	 * 是否启用Swagger
	 */
	private boolean enabled = true;

	/**
	 * 指定服务器地址
	 */
	private String host = HostUtils.getHost();

	/**
	 * 聚合文档地址(当前服务重启后请求重新加载当前服务时需要用到)
	 */
	private String managerUrl;

	/**
	 * 显示级别(用于控制文档显示范围)
	 */
	private int level = 0;

	/**
	 * 在设置的文档聚合中心无法访问时是否允许提供单体文档服务
	 */
	private boolean allowSingle = true;

	/**
	 * 是否显示访问包路径
	 */
	private boolean showPath = true;

	/**
	 * 服务基础路径
	 */
	private String basePath = "/";

	/**
	 * 版本
	 */
	private String version = MavenUtils.getModel().getVersion();

	/**
	 * 项目代码托管地址
	 */
	private String url = MavenUtils.getModel().getScm().getUrl();

	/**
	 * 子服务地址
	 */
	private List<String> urls = Lists.newList();

	/**
	 * 分组列表
	 */
	private List<SwaggerProperties> SwaggerProperties = Lists.newList();

	public String getHost() {
		return host;
	}

	public EasySwaggerConfiguration setHost(String host) {
		this.host = host;
		return this;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public EasySwaggerConfiguration setEnabled(boolean enabled) {
		this.enabled = enabled;
		return this;
	}

	public String getVersion() {
		return version;
	}

	public EasySwaggerConfiguration setVersion(String version) {
		this.version = version;
		return this;
	}

	public int getLevel() {
		return level;
	}

	public EasySwaggerConfiguration setLevel(int level) {
		this.level = level;
		return this;
	}

	public boolean isAllowSinglen() {
		return allowSingle;
	}

	public EasySwaggerConfiguration setAllowSinglen(boolean allowSingle) {
		this.allowSingle = allowSingle;
		return this;
	}

	public String getManagerUrl() {
		if (managerUrl != null && !managerUrl.endsWith("/")) {
			managerUrl = managerUrl + "/";
		}
		return managerUrl;
	}

	public EasySwaggerConfiguration setManagerUrl(String managerUrl) {
		this.managerUrl = managerUrl;
		return this;
	}

	public boolean isShowPath() {
		return showPath;
	}

	public EasySwaggerConfiguration setShowPath(boolean showPath) {
		this.showPath = showPath;
		return this;
	}

	public List<String> getUrls() {
		return urls;
	}

	public EasySwaggerConfiguration setUrls(List<String> urls) {
		this.urls.addAll(urls);
		return this;
	}

	public EasySwaggerConfiguration addUrls(String... urls) {
		this.urls.addAll(Arrays.asList(urls));
		return this;
	}

	public String getUrl() {
		return url;
	}

	public EasySwaggerConfiguration setUrl(String url) {
		this.url = url;
		return this;
	}

	public List<SwaggerProperties> getSwaggerProperties() {
		if (SwaggerProperties.isEmpty()) {
			SwaggerProperties.add(new SwaggerProperties());
		}
		return SwaggerProperties;
	}

	public EasySwaggerConfiguration setSwaggerProperties(List<SwaggerProperties> SwaggerProperties) {
		this.SwaggerProperties.addAll(SwaggerProperties);
		return this;
	}

	public EasySwaggerConfiguration addSwaggerProperties(String groupName, String title, String description,
			String groupPackage, String groupPath, Developer... developers) {
		this.SwaggerProperties.add(new SwaggerProperties(groupName, title, description, groupPackage, groupPath,
				Arrays.asList(developers)));
		return this;
	}

	public EasySwaggerConfiguration addSwaggerProperties(String groupName, String title, String description,
			String groupPackage, Developer... developers) {
		this.SwaggerProperties
				.add(new SwaggerProperties(groupName, title, description, groupPackage, Arrays.asList(developers)));
		return this;
	}

	public EasySwaggerConfiguration addSwaggerProperties(String groupName, String title, String description,
			Developer... developers) {
		this.SwaggerProperties.add(new SwaggerProperties(groupName, title, description, Arrays.asList(developers)));
		return this;
	}

	public EasySwaggerConfiguration addSwaggerProperties(String groupName, String title, Developer... developers) {
		this.SwaggerProperties.add(new SwaggerProperties(groupName, title, Arrays.asList(developers)));
		return this;
	}

	public EasySwaggerConfiguration addSwaggerProperties(String groupName, Developer... developers) {
		this.SwaggerProperties.add(new SwaggerProperties(groupName, Arrays.asList(developers)));
		return this;
	}

	public EasySwaggerConfiguration addSwaggerProperties(Developer... developers) {
		this.SwaggerProperties.add(new SwaggerProperties(Arrays.asList(developers)));
		return this;
	}

	public EasySwaggerConfiguration addSwaggerProperties(String groupName) {
		this.SwaggerProperties.add(new SwaggerProperties(groupName));
		return this;
	}

	public String getBasePath() {
		return basePath;
	}

	public EasySwaggerConfiguration setBasePath(String basePath) {
		this.basePath = basePath;
		return this;
	}

	public EasySwaggerConfiguration addModel(Class<?> type) {
		models.add(typeResolver.resolve(type));
		return this;
	}

	public EasySwaggerConfiguration addModel(ResolvedType resolvedType) {
		models.add(resolvedType);
		return this;
	}

	public EasySwaggerConfiguration addModels(ResolvedType[] resolvedTypes) {
		models.addAll(Arrays.asList(resolvedTypes));
		return this;
	}

	public EasySwaggerConfiguration addParamterModel(String name, ParameterBuilder parameterBuilder) {
		parameters.put(name, parameterBuilder);
		return this;
	}

	public EasySwaggerConfiguration addParamterModels(Map<String, ParameterBuilder> parameters) {
		EasySwaggerConfiguration.parameters.putAll(parameters);
		return this;
	}

	public EasySwaggerConfiguration addResponseMessage(int code, String msg) {
		responseMessages.put(code, new ResponseMessage(msg));
		return this;
	}

	public EasySwaggerConfiguration addResponseMessage(int code, ResponseMessage responseMessage) {
		responseMessages.put(code, responseMessage);
		return this;
	}

	public EasySwaggerConfiguration addResponseMessages(Map<Integer, ResponseMessage> responseMessages) {
		EasySwaggerConfiguration.responseMessages.putAll(responseMessages);
		return this;
	}

	public EasySwaggerConfiguration defaultErrorModel(Class<?> defaultErrorModel) {
		setDefaultErrorModel(defaultErrorModel);
		return this;
	}

	@Override
	public String toString() {
		return JsonUtils.toJson(this);
	}

	/**
	 * swagger配置
	 *
	 */
	public class SwaggerProperties {

		/**
		 * 文档分组名称
		 */
		private String groupName = MavenUtils.getModel().getName();

		/**
		 * 文档分组路由
		 */
		private String groupPath = "/**";

		/**
		 * 文档分组路径
		 */
		private String groupPackage = AppUtils.getMainPackagePath();

		/**
		 * 文档标题
		 */
		private String title = MavenUtils.getModel().getName();

		/**
		 * 描述
		 */
		private String description = MavenUtils.getModel().getDescription();

		/**
		 * 开发人员列表
		 */
		private List<Developer> developers = MavenUtils.getModel().getDevelopers();

		public SwaggerProperties() {
		}

		public SwaggerProperties(String groupName) {
			this.groupName = groupName;
		}

		public SwaggerProperties(List<Developer> developers) {
			this.developers = developers;
		}

		public SwaggerProperties(String groupName, List<Developer> developers) {
			this.groupName = groupName;
			this.developers = developers;
		}

		public SwaggerProperties(String groupName, String title, List<Developer> developers) {
			this.groupName = groupName;
			this.title = title;
			this.developers = developers;
		}

		public SwaggerProperties(String groupName, String title, String description, List<Developer> developers) {
			this.groupName = groupName;
			this.title = title;
			this.description = description;
			this.developers = developers;
		}

		public SwaggerProperties(String groupName, String title, String description, String groupPackage,
				List<Developer> developers) {
			this.groupName = groupName;
			this.title = title;
			this.groupPackage = groupPackage;
			this.description = description;
			this.developers = developers;
		}

		public SwaggerProperties(String groupName, String title, String description, String groupPackage,
				String groupPath, List<Developer> developers) {
			this.groupName = groupName;
			this.title = title;
			this.groupPath = groupPath;
			this.groupPackage = groupPackage;
			this.description = description;
			this.developers = developers;
		}

		public String getTitle() {
			return title;
		}

		public SwaggerProperties setTitle(String title) {
			this.title = title;
			return this;
		}

		public String getDescription() {
			return description;
		}

		public SwaggerProperties setDescription(String description) {
			this.description = description;
			return this;
		}

		public String getGroupName() {
			return groupName;
		}

		public SwaggerProperties setGroupName(String groupName) {
			this.groupName = groupName;
			return this;
		}

		public String getGroupPath() {
			return groupPath;
		}

		public void setGroupPath(String groupPath) {
			this.groupPath = groupPath;
		}

		public SwaggerProperties setDevelopers(List<Developer> developers) {
			this.developers = developers;
			return this;
		}

		public List<Developer> getDevelopers() {
			return developers;
		}

		public String getGroupPackage() {
			return groupPackage;
		}

		public void setGroupPackage(String groupPackage) {
			this.groupPackage = groupPackage;
		}
	}
}
